local game = require "club.threecard.roulette"
local bet_areas = game.config.bet_areas;

local bet_area_gen = game.ui.element()

function bet_area_gen:ctor()
    self.res = "club.threecard.roulette/ui/ingame.b:bet_area_gen"
end

local GameObjectExtension = CS.Blaze.GameObjectExtension
local Vector3 = CS.UnityEngine.Vector3
local Vector2 = CS.UnityEngine.Vector2

local create_element = function(self, id, x, y)
    local obj = GameObjectExtension.GetFromPool(self.temp);
    obj.transform:SetParent(self.root, false);
    obj.transform.localPosition = Vector3(x, y, 0);
    obj.name = id;

    self[id] = obj;
end

local find_min_x = function(self, nums)
    local min_x = 9999;
    for _, num in ipairs(nums) do
        min_x = math.min(min_x, self[num].transform.localPosition.x)
    end

    return min_x;
end

local find_min_y = function(self, nums)
    local min_y = 9999;
    for _, num in ipairs(nums) do
        min_y = math.min(min_y, self[num].transform.localPosition.y)
    end

    return min_y;
end

local find_max_x = function(self, nums)
    local max_x = -9999;
    for _, num in ipairs(nums) do
        max_x = math.max(max_x, self[num].transform.localPosition.x)
    end

    return max_x;
end

local find_max_y = function(self, nums)
    local max_y = -9999;
    for _, num in ipairs(nums) do
        max_y = math.max(max_y, self[num].transform.localPosition.y)
    end

    return max_y;
end

-- 奇数判定
local is_odd_num = function(nums)
    for _, num in ipairs(nums) do
        if num % 2 ~= 1 then
            return false;
        end
    end

    return true;
end

-- 偶数判定
local is_even_num = function(nums)
    for _, num in ipairs(nums) do
        if num % 2 ~= 0 then
            return false;
        end
    end

    return true;
end

-- 大
local is_big_num = function(nums)
    for _, num in ipairs(nums) do
        if num <= 18 then
            return false;
        end
    end

    return true;
end

-- 小
local is_small_num = function(nums)
    for _, num in ipairs(nums) do
        if num > 18 then
            return false;
        end
    end

    return true;
end

local is_red_num = function(nums)
    for _, num in ipairs(nums) do
        if num == 2 or num == 4 or num == 6 or num == 8 or num == 10 or num == 11 or num == 13 or num == 15
        or num == 17 or num == 20 or num == 22 or num == 24 or num == 26 or num == 28 or num == 29 or num == 31
        or num == 33 or num == 35 then
            return false;
        end
    end

    return true;
end

local is_black_num = function(nums)
    for _, num in ipairs(nums) do
        if num == 1 or num == 3 or num == 5 or num == 7 or num == 9 or num == 12 or num == 14 or num == 16
        or num == 18 or num == 19 or num == 21 or num == 23 or num == 25 or num == 27 or num == 30 or num == 32
        or num == 34 or num == 36 then
            return false;
        end
    end

    return true;
end 

function bet_area_gen:gen()
    local interval_x = 67.1;
    local interval_y = 80;

    local start_x = 0;
    local start_y = 0;

    -- 先生成基本元素
    -- 0
    create_element(self, 0, 0-interval_x, 0+interval_y);
    -- 1-36
    for k=0, (36/3)-1 do
        for i = 0, 2 do
            local y = start_y + i * interval_y;
            local x = start_x + k * interval_x;
            local id = k*3 + (i+1);
            create_element(self, id, x, y);
        end
    end

    --根据基本元素生成关联元素 2个关联
    for _, v in ipairs(bet_areas) do
        if #v.nums == 2 then
            local x = 0;
            local y = 0;
            for _, id in ipairs(v.nums) do
                local element = self[id];
                if not element then
                    log.error("不是基础元素 id"..id);
                end

                x = x + element.transform.localPosition.x;
                y = y + element.transform.localPosition.y;
            end

            x = x/#v.nums;
            y = y/#v.nums;

            create_element(self, v.id, x, y);

            local o1 = self[v.nums[1]];
            local o2 = self[v.nums[2]];
            local w = o1.transform.localPosition.x - o2.transform.localPosition.x;
            local h = o1.transform.localPosition.y - o2.transform.localPosition.y;
            local o1_rect = o1.transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
            local o2_rect = o2.transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
            local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));

            local interval = 0;
            w = math.abs(w)
            h = math.abs(h)
            if w > 0 then
                rect.sizeDelta = Vector2(w - (o1_rect.sizeDelta.x + o2_rect.sizeDelta.x)/2 - interval,rect.sizeDelta.y);
            end

            if h > 0 then
                rect.sizeDelta = Vector2(rect.sizeDelta.x, h - (o1_rect.sizeDelta.y + o2_rect.sizeDelta.y)/2 - interval);
            end
        end
    end

    --根据基本元素生成关联元素 3个元素
    for _, v in ipairs(bet_areas) do
        if #v.nums == 3 then
            -- 0, 1, 2 or 0, 2, 3 特殊处理
            if (v.nums[1] == 0 and v.nums[2] == 1 and v.nums[3] == 2) or 
                (v.nums[1] == 0 and v.nums[2] == 2 and v.nums[3] == 3)
            then
                local min_x = find_min_x(self, v.nums);
                local max_x = find_max_x(self, v.nums);
                local min_y = find_min_y(self, v.nums);
                local max_y = find_max_y(self, v.nums);

                local x = (max_x + min_x) /2;
                local y = (max_y + min_y) /2;

                create_element(self, v.id, x, y);
                local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
                rect.sizeDelta = Vector2(17.1, 19.7);
            else
                local min_x = find_min_x(self, v.nums);
                local min_y = find_min_y(self, v.nums);

                local x = min_x;
                local y = (min_y - interval_y + min_y) /2
                create_element(self, v.id, x, y);
                local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
                rect.sizeDelta = Vector2(50, 19.7);
            end
        end
    end

    --根据基本元素生成关联元素 4个元素
    for _, v in ipairs(bet_areas) do
        if #v.nums == 4 then
            -- 0, 1, 2, 3 特殊处理
            if v.nums[1] == 0 and v.nums[2] == 1 and v.nums[3] == 2 and v.nums[4] == 3 then
                local x = (self[0].transform.localPosition.x + self[1].transform.localPosition.x) /2;
                local y = ((self[1].transform.localPosition.y - interval_y) + self[1].transform.localPosition.y) /2;
                create_element(self, v.id, x, y);

                local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
                rect.sizeDelta = Vector2(17.1, 19.7);
            else
                local x = 0;
                local y = 0;
                for _, id in ipairs(v.nums) do
                    local element = self[id];
                    if not element then
                        log.error("不是基础元素 id"..id);
                    end
    
                    x = x + element.transform.localPosition.x;
                    y = y + element.transform.localPosition.y;
                end
    
                x = x/#v.nums;
                y = y/#v.nums;

                create_element(self, v.id, x, y);
                local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
                rect.sizeDelta = Vector2(17.1, 19.7);
            end
        end
    end

    --根据基本元素生成关联元素 6个元素
    for _, v in ipairs(bet_areas) do
        if #v.nums == 6 then
            local min_x = find_min_x(self, v.nums);
            local max_x = find_max_x(self, v.nums);
            local min_y = find_min_y(self, v.nums);

            local x = (min_x + max_x)/2;
            local y = (min_y - interval_y + min_y)/2;
            create_element(self, v.id, x, y);
            local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
            rect.sizeDelta = Vector2(17.1, 19.7);
        end
    end

     --根据基本元素生成关联元素 12个元素
     for _, v in ipairs(bet_areas) do
        if #v.nums == 12 then
            table.sort(v.nums, function(a, b)
                return a < b;
            end);

            local dif = v.nums[2] - v.nums[1];
            if dif == 1 then
                local min_x = find_min_x(self, v.nums);
                local max_x = find_max_x(self, v.nums);
                local min_y = find_min_y(self, v.nums);
                local x = (min_x + max_x)/2;
                local y = min_y - interval_y
                create_element(self, v.id, x, y);
                local rect = self[v.id].transform:Find("img"):GetComponent(typeof(CS.UnityEngine.RectTransform));
                rect.sizeDelta = Vector2(rect.sizeDelta.x*4, 29);
            elseif dif == 3 then
                local max_x = find_max_x(self, v.nums);
                local max_y = find_max_y(self, v.nums);
                local x = max_x + interval_x;
                local y = max_y;
                create_element(self, v.id, x, y);
            end
        end
     end

    --根据基本元素生成关联元素 18个元素
    start_x = 36.3;
    start_y = -109.2;
    interval_x = 132.6

    for _, v in ipairs(bet_areas) do
        if #v.nums == 18 then
            local x = 0;
            local y = 0;
            if is_small_num(v.nums) then
                x = start_x;
                y = start_y;
            elseif is_even_num(v.nums) then
                x = start_x + interval_x * 1;
                y = start_y;
            elseif is_red_num(v.nums) then
                x = start_x + interval_x * 2;
                y = start_y;
            elseif is_black_num(v.nums) then
                x = start_x + interval_x * 3;
                y = start_y;
            elseif is_odd_num(v.nums) then
                x = start_x + interval_x * 4;
                y = start_y;
            elseif is_big_num(v.nums) then
                x = start_x + interval_x * 5;
                y = start_y;
            end

            create_element(self, v.id, x, y);
        end
    end
end

bet_area_gen.is_odd_num = is_odd_num
bet_area_gen.is_even_num = is_even_num
bet_area_gen.is_big_num = is_big_num
bet_area_gen.is_small_num = is_small_num
bet_area_gen.is_red_num = is_red_num
bet_area_gen.is_black_num = is_black_num

return bet_area_gen